import type { CascaderNode } from "element-plus";
import type { DeptDetailResult } from "@/api/types";
import { computed, defineComponent, onMounted, ref } from "vue";
import { deptApi } from "@/api";
import { userDeptStorage } from "@/config/storage";
import { $t } from "@/plugins/i18n";
import { useUserDeptStore } from "@/stores/userDept";

interface Props {
    /** 是否启用懒加载, 如果部门数据量较大则建议开启 */
    lazy?: boolean;
    /** 最大加载层数, 从 1 开始, -1 表示不限制 */
    maxLevel?: number;
    /** 可以被选中的层级, 空数组表示全部可选 */
    selectedLevel?: number[];
    /** 是否可以选择任意一级 */
    checkStrictly?: boolean;
    /** 是否显示完整路径 */
    showAllLevels?: boolean;
    /** 是否可以清空 */
    clearable?: boolean;
    /** 是否可搜索 */
    filterable?: boolean;
    /** 占位符 */
    placeholder?: string;
}

export default defineComponent((props: Props, { attrs, emit }) => {
    const { lazy } = props;
    const maxLevel = computed(() => props.maxLevel ?? -1);
    const selectedLevel = computed(() => props.selectedLevel ?? []);
    const checkStrictly = computed(() => props.checkStrictly ?? true);
    const showAllLevels = computed(() => props.showAllLevels ?? true);
    const clearable = computed(() => props.clearable ?? true);
    const filterable = computed(() => props.filterable ?? true);
    const placeholder = computed(() => props.placeholder ?? $t("placeholder.searchOrg"));

    /** 当前用户的部门 */
    const userDeptId = useUserDeptStore().id;
    const userDeptCode = useUserDeptStore().code;

    /** 选中的值 */
    const selectedValue = ref<string[]>([]);

    // #region ================= 加载全部数据 =================

    const cascaderData = ref<DeptDetailResult[]>([]);

    const getData = (): void => {
        if (lazy) return;
        deptApi.listTree(userDeptCode).then((resp) => {
            if (ok(resp)) {
                cascaderData.value = processTreeData(resp.data);
            }
        });
    };

    /** 处理树形数据，设置 disabled 和 isLeaf 属性 */
    const processTreeData = (data: DeptDetailResult[]): DeptDetailResult[] => {
        return data.map((item) => {
            const processedItem = { ...item };

            // 限制最大层数
            if (maxLevel.value >= 0 && item.level >= maxLevel.value) {
                processedItem.isLeaf = true;
                processedItem.children = null;
            }

            // 设置不可选中的层级
            if (selectedLevel.value.length !== 0 && !selectedLevel.value.includes(item.level)) {
                processedItem.disabled = true;
            }

            // 递归处理子节点
            if (processedItem.children && processedItem.children.length > 0) {
                processedItem.children = processTreeData(processedItem.children);
            }

            return processedItem;
        });
    };

    onMounted(() => {
        getData();
        // 初始化时选中当前用户部门
        if (userDeptStorage.value) {
            const codes = userDeptStorage.value.code.split(".");
            selectedValue.value = codes;
            emit("change", userDeptStorage.value);
        }
    });

    // #endregion ================= 加载全部数据 ==============
    // #region ==================== 懒加载 ===================

    /** 懒加载方法 */
    const lazyLoad = (node: CascaderNode, resolve: (dataList: any[]) => void): void => {
        const { level } = node;

        if (level === 0) {
            // 加载根节点（当前用户部门）
            deptApi.findById(userDeptId).then((resp) => {
                if (ok(resp)) {
                    const dept = resp.data;
                    // 限制最大层数
                    if (maxLevel.value >= 0 && dept.level >= maxLevel.value) {
                        dept.isLeaf = true;
                    }
                    // 设置不可选中的层级
                    if (selectedLevel.value.length !== 0 && !selectedLevel.value.includes(dept.level)) {
                        dept.disabled = true;
                    }
                    resolve([dept]);
                }
            });
        } else {
            // 加载子节点
            const parentData = node.data as unknown as DeptDetailResult;
            deptApi.listChildren(parentData.id).then((resp) => {
                if (ok(resp)) {
                    const processedData = resp.data.map((dept) => {
                        // 限制最大层数
                        if (maxLevel.value >= 0 && dept.level >= maxLevel.value) {
                            dept.isLeaf = true;
                        }
                        // 设置不可选中的层级
                        if (selectedLevel.value.length !== 0 && !selectedLevel.value.includes(dept.level)) {
                            dept.disabled = true;
                        }
                        return dept;
                    });
                    resolve(processedData);
                }
            });
        }
    };

    // #endregion ================= 懒加载 ===================
    // #region ==================== 搜索 =====================

    /** 搜索方法 */
    const filterMethod = (node: CascaderNode, keyword: string): boolean => {
        const data = node.data as unknown as DeptDetailResult;
        return data.name.toLowerCase().includes(keyword.toLowerCase());
    };

    // #endregion ================= 搜索 =====================
    // #region ==================== 事件处理 =================

    /** 值改变时触发 */
    const handleChange = (value: string | string[]): void => {
        if (!value || (Array.isArray(value) && value.length === 0)) {
            emit("change", null);
            return;
        }

        // 获取选中节点的完整数据
        const codes = Array.isArray(value) ? value : [value];
        const code = codes.join(".");

        // 从级联数据中查找对应的部门信息
        const findDeptByCode = (data: DeptDetailResult[], targetCode: string): DeptDetailResult | null => {
            for (const item of data) {
                if (item.code === targetCode) {
                    return item;
                }
                if (item.children && item.children.length > 0) {
                    const found = findDeptByCode(item.children, targetCode);
                    if (found) return found;
                }
            }
            return null;
        };

        let selectedDept: DeptDetailResult | null = null;
        if (lazy) {
            // 懒加载模式下，需要从接口获取完整数据
            const lastCode = codes[codes.length - 1];
            const payload = {
                name: lastCode,
                code: userDeptCode,
                maxLevel: maxLevel.value,
            };
            // TODO 这里可以通过 code 查询，暂时通过 name 搜索
            deptApi.listByName(payload).then((resp) => {
                if (ok(resp) && resp.data.length > 0) {
                    selectedDept = resp.data.find(d => d.code === code) || resp.data[0];
                    emit("change", selectedDept);
                }
            });
        } else {
            selectedDept = findDeptByCode(cascaderData.value, code);
            emit("change", selectedDept);
        }
    };

    // #endregion ================= 事件处理 =================

    /** 级联选择器配置 */
    const cascaderProps = computed(() => ({
        value: "code",
        label: "name",
        children: "children",
        disabled: "disabled",
        leaf: "isLeaf",
        checkStrictly: checkStrictly.value,
        lazy,
        lazyLoad: lazy ? lazyLoad : undefined,
    }));

    return () => (
        <div>
            <el-cascader
                {...attrs}
                v-model={selectedValue.value}
                options={cascaderData.value}
                props={cascaderProps.value}
                clearable={clearable.value}
                filterable={filterable.value}
                filter-method={filterMethod}
                show-all-levels={showAllLevels.value}
                placeholder={placeholder.value}
                onChange={handleChange}
                style={{ width: "100%" }}
            />
        </div>
    );
}, {
    name: "DeptCascader",
    props: {
        lazy: {
            type: Boolean,
            default: true,
        },
        maxLevel: {
            type: Number,
            default: -1,
        },
        selectedLevel: {
            type: Array,
            default: () => [],
        },
        checkStrictly: {
            type: Boolean,
            default: true,
        },
        showAllLevels: {
            type: Boolean,
            default: true,
        },
        clearable: {
            type: Boolean,
            default: true,
        },
        filterable: {
            type: Boolean,
            default: false,
        },
        placeholder: {
            type: String,
            default: "",
        },
    },
    emits: {
        /** 选中值发生变化时触发 */
        change: (data: DeptDetailResult | null) => data === null || data instanceof Object,
    },
});
